package myoa

import myoa.domain.UserStatus
import myoa.tool.SessionTool
import org.apache.commons.dbcp.BasicDataSource
import org.apache.shiro.SecurityUtils
import org.apache.shiro.authc.AuthenticationException
import org.apache.shiro.authc.UsernamePasswordToken
import org.apache.shiro.web.util.SavedRequest
import org.apache.shiro.web.util.WebUtils
import org.apache.shiro.grails.ConfigUtils
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy

class AuthController {
    def shiroSecurityManager

    def index = { redirect(action: "login", params: params) }

    // refer targetUri in ShiroGrailsPlugin
    def login = {
        TransactionAwareDataSourceProxy d1 = (TransactionAwareDataSourceProxy) applicationContext.getBean('dataSource')
        BasicDataSource d2 = (BasicDataSource) d1.targetDataSource
        [username: params.username, rememberMe: (params.rememberMe != null), targetUri: params.targetUri, dataSource: d2]
    }

    def signIn = {
        def authToken = new UsernamePasswordToken(params.username, params.password as String)

        // Support for "remember me"
        if (params.rememberMe) {
            authToken.rememberMe = true
        }

        // If a controller redirected to this page, redirect back
        // to it. Otherwise redirect to the root URI.
        def targetUri = params.targetUri ?: "/"

        // Handle requests saved by Shiro filters.
        def savedRequest = WebUtils.getSavedRequest(request)
        if (savedRequest) {
            targetUri = savedRequest.requestURI - request.contextPath
            if (savedRequest.queryString) targetUri = targetUri + '?' + savedRequest.queryString
        }

        try {
            // Perform the actual login. An AuthenticationException
            // will be thrown if the username is unrecognised or the
            // password is incorrect.
            SecurityUtils.subject.login(authToken)

            User user = User.findByName(authToken.username) //todo added by jcat
            SessionTool.loginUser = user
            if (user.status == UserStatus.PasswordExpired) {
                flash.message = message(code: 'user.password.expired')
                redirect(controller: 'user', action: 'changePassword', id: user.id)
            } else {
                log.info "${user.name} login success"
                user.lastLogin = new Date()
                flash.message = message(code: 'home.welcome')
                redirect(uri: targetUri)
            }
        }
        catch (AuthenticationException ex) {
            // Authentication failed, so display the appropriate message
            // on the login page.
            log.info "${params.username} login failed"
            flash.message = message(code: "default.login.failed")

            // Keep the username and "remember me" setting so that the
            // user doesn't have to enter them again.
            def m = [username: params.username]
            if (params.rememberMe) {
                m["rememberMe"] = true
            }

            // Remember the target URI too.
            if (params.targetUri) {
                m["targetUri"] = params.targetUri
            }

            // Now redirect back to the login page.
            redirect(action: "login", params: m)
        }
    }

    def signOut = {
        // Log the user out of the application.
        def principal = SecurityUtils.subject?.principal
        SecurityUtils.subject?.logout()
        // For now, redirect back to the home page.
        if (ConfigUtils.getCasEnable() && ConfigUtils.isFromCas(principal)) {
            redirect(uri: ConfigUtils.getLogoutUrl())
        } else {
            redirect(uri: "/")
        }
        ConfigUtils.removePrincipal(principal)
    }

    //refer to ShiroGrailsPlugin
    def unauthorized(String targetUri) {

    }
}
